package com.jiubanqingchen.future.publish.run;

import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.wall.WallFilter;
import com.jfinal.config.*;
import com.jfinal.ext.handler.ContextPathHandler;
import com.jfinal.ext.interceptor.SessionInViewInterceptor;
import com.jfinal.json.FastJsonFactory;
import com.jfinal.kit.Prop;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.dialect.MysqlDialect;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.plugin.druid.DruidStatViewHandler;
import com.jfinal.plugin.ehcache.EhCachePlugin;
import com.jfinal.render.ViewType;
import com.jfinal.template.Engine;
import com.jfinal.template.source.ClassPathSourceFactory;
import com.jiubanqingchen.future.cms.config.CmsRoute;
import com.jiubanqingchen.future.cms.index.IndexController;
import com.jiubanqingchen.future.common.plugin.quartz.QuartzPlugin;
import com.jiubanqingchen.future.common.directive.ParaLikeDirective;
import com.jiubanqingchen.future.generator.config.GeneratorRoute;
import com.jiubanqingchen.future.model.models._MappingKit;
import com.jiubanqingchen.future.org.config.OrgRoute;
import com.jiubanqingchen.future.org.hanlder.WebSocketHandler;
import com.jiubanqingchen.future.org.interceptor.AuthorityInterceptor;
import com.jiubanqingchen.future.org.interceptor.OperateLogInterceptor;
import com.jiubanqingchen.future.org.interceptor.OrgInterceptor;

public class MainConfig extends JFinalConfig {
    /**
     * 将全局配置提出来 方便其他地方重用
     *
     * @author Light_Dust
     */
    private static Prop p;
    private WallFilter wallFilter;

    /**
     * 配置JFinal常量
     *
     * @author Light_Dust
     */
    @Override
    public void configConstant(Constants me) {
        // 读取数据库配置文件
        loadConfig();
        // 设置当前是否为开发模式
        me.setDevMode(p.getBoolean("devMode"));
        // 设置默认上传文件保存路径 getFile等使用
        me.setBaseUploadPath("upload/temp/");
        // 设置上传最大限制尺寸
        me.setMaxPostSize(1024 * 1024 * 10);
        // 设置默认下载文件路径 renderFile使用
        me.setBaseDownloadPath("download");
        // 设置默认视图类型
        me.setViewType(ViewType.JFINAL_TEMPLATE);
        // 设置404渲染视图
        // me.setError404View("404.html");
        // 设置json工厂
        me.setJsonFactory(FastJsonFactory.me());
        // 设置启用依赖注入
        me.setInjectDependency(true);
        // 开启超类注入
        me.setInjectSuperClass(true);
        me.setToSlf4jLogFactory();
    }

    /**
     * (非 Javadoc)
     *
     * @param me
     * @author Light_Dust
     * @date 2019年7月4日 下午1:49:20
     * @see JFinalConfig#configRoute(Routes)
     */
    @Override
    public void configRoute(Routes me) {
        // 配置首页根路由
        me.add("/", IndexController.class);
        //设置超类action
        me.setMappingSuperClass(true);
        //后台管理路由
        me.add(new OrgRoute());
        // 后台系统路由
        me.add(new CmsRoute());
        //生成模块路由
        me.add(new GeneratorRoute());
    }

    /**
     * @param
     * @return void 返回类型
     * @throws @author Light_Dust
     * @Title: loadConfig
     * @Description: (先加载开发环境配置 ， 再追加生产环境的少量配置覆盖掉开发环境配置)
     * @date 2019年7月4日 下午1:51:10
     */
    static void loadConfig() {
        if (p == null) {
            p = PropKit.use("future-template.properties");
        }
    }

    /**
     * 获取数据库插件 抽取成独立的方法，便于重用该方法，减少代码冗余
     *
     * @author Light_Dust
     */
    public static DruidPlugin getDruidPlugin() {
        loadConfig();
        return new DruidPlugin(p.get("jdbcUrl"), p.get("user"), p.get("password"));
    }

    /**
     * 配置JFinal插件 数据库连接池 ActiveRecordPlugin 缓存 定时任务 自定义插件
     *
     * @author Light_Dust
     */
    @Override
    public void configPlugin(Plugins me) {
        loadConfig();
        // 配置数据库连接池插件
        DruidPlugin dbPlugin = getDruidPlugin();
        // 加强数据库安全
        wallFilter = new WallFilter();
        wallFilter.setDbType("mysql");
        dbPlugin.addFilter(wallFilter);
        // 添加 StatFilter 才会有统计数据
        dbPlugin.addFilter(new StatFilter());

        // 数据映射 配置ActiveRecord插件
        ActiveRecordPlugin arp = new ActiveRecordPlugin(dbPlugin);
        arp.setShowSql(p.getBoolean("devMode"));
        arp.setDialect(new MysqlDialect());
        dbPlugin.setDriverClass("com.mysql.jdbc.Driver");
        me.add(dbPlugin);
        //ehcache缓存
        me.add(new EhCachePlugin());

        //添加映射
        arp.getEngine().setSourceFactory(new ClassPathSourceFactory());

        addSqlTemplates(arp);
        addDirectives(arp);

        addMapping(arp);
        me.add(arp);

        //添加定时任务插件 quartzPlugin必须在完成arp映射之后添加因为我使用了对象查询
        me.add(new QuartzPlugin());
    }

    /**
     * 设置sql模板文件,方便子类调用
     *
     * @param arp
     */
    public void addSqlTemplates(ActiveRecordPlugin arp) {
        arp.addSqlTemplate("future-org/index.sql");
        arp.addSqlTemplate("future-cms/index.sql");
        arp.addSqlTemplate("future-generator/index.sql");
    }

    /**
     * 设置sql指令,方便子类调用
     *
     * @param arp
     */
    public void addDirectives(ActiveRecordPlugin arp) {
        Engine engine = arp.getEngine();
        engine.setCompressorOn(' ');//设置sql 空格优化
        engine.addDirective("paraLike", ParaLikeDirective.class);
    }

    /**
     * 添加mapping映射
     *
     * @param arp
     */
    public void addMapping(ActiveRecordPlugin arp) {
        _MappingKit.mapping(arp);
    }


    /**
     * 配置全局拦截器
     *
     * @author Light_Dust
     */
    @Override
    public void configInterceptor(Interceptors me) {
        me.addGlobalActionInterceptor(new SessionInViewInterceptor());
        me.addGlobalActionInterceptor(new OrgInterceptor());
        me.addGlobalActionInterceptor(new AuthorityInterceptor());
        me.addGlobalActionInterceptor(new OperateLogInterceptor());
    }

    /**
     * 配置全局处理器
     *
     * @author Light_Dust
     */
    @Override
    public void configHandler(Handlers me) {
        me.add(new ContextPathHandler("ctx"));
        me.add(new WebSocketHandler());
        DruidStatViewHandler druidStatViewHandler = new DruidStatViewHandler("/druid");
        me.add(druidStatViewHandler);
    }

    /**
     * 项目启动后调用
     *
     * @author Light_Dust
     */
    @Override
    public void onStart() {
        wallFilter.getConfig().setSelectUnionCheck(false);
    }

    /**
     * 配置模板引擎
     *
     * @author Light_Dust
     */
    @Override
    public void configEngine(Engine me) {
        me.setDevMode(p.getBoolean("engineDevMode", true));
    }


}
